package com.base.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 所有控制器的切面
 *
 * @author: wnhuang
 * @date: 2020/1/6 16:43
 */
@Aspect
@Order(10)
@Component
public class CotrollerInterceptor {
    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 指定切入点
     */
    @Pointcut("execution(* com.base.controller..*(..))")
    public void cotrollerPointcut() {
    }

    /**
     * 环绕通知： 环绕通知非常强大，可以决定目标方法是否执行，什么时候执行，执行时是否需要替换方法参数，执行完毕是否需要替换返回值。 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     */
    @Around("cotrollerPointcut()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object obj = null;
        try {
            logger.debug("HTTP请求方法:".concat("[").concat(proceedingJoinPoint.getTarget().getClass().getName()).concat("#").concat(proceedingJoinPoint.getSignature().getName()).concat("]"));
            logger.debug("HTTP请求参数:".concat(getArgs(proceedingJoinPoint)));
            obj = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            logger.error("HTTP请求发生异常:{}", throwable.getMessage());
            throwable.printStackTrace();
            throw throwable;
        }
        long end = System.currentTimeMillis();
        logger.debug("HTTP请求处理用时:".concat(String.valueOf(end - start)).concat("ms"));
        logger.debug("HTTP请求返回值:".concat(obj == null ? "void" : new ObjectMapper().writeValueAsString(obj)));
        return obj;
    }

    /**
     * 获取入参
     *
     * @param proceedingJoinPoint proceedingJoinPoint
     * @return 入参
     */
    private String getArgs(ProceedingJoinPoint proceedingJoinPoint) {
        StringBuffer sb = new StringBuffer("[");
        for (Object object : proceedingJoinPoint.getArgs()) {
            sb.append(object);
            sb.append(", ");
        }
        if (sb.length() > 1) {
            sb.delete((sb.length() - 2), sb.length());
        }
        sb.append("]");
        return sb.toString();
    }
}
